home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_023 / ver30 / file.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  9KB  |  380 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *         File commands.
  4.  * Version:    29
  5.  * Last edit:    05-Feb-86
  6.  * By:        rex::conroy
  7.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  8.  */
  9. #include    "def.h"
  10.  
  11. /*
  12.  * Read a file into the current
  13.  * buffer. This is really easy; all you do it
  14.  * find the name of the file, and call the standard
  15.  * "read a file into the current buffer" code.
  16.  */
  17. fileread(f, n, k)
  18. {
  19.     register int    s;
  20.     char        fname[NFILEN];
  21.  
  22.     if ((s=ereply("Read file: ", fname, NFILEN)) != TRUE)
  23.         return (s);
  24.     adjustcase(fname);
  25.     return (readin(fname));
  26. }
  27.  
  28. /*
  29.  * Select a file for editing.
  30.  * Look around to see if you can find the
  31.  * fine in another buffer; if you can find it
  32.  * just switch to the buffer. If you cannot find
  33.  * the file, create a new buffer, read in the
  34.  * text, and switch to the new buffer.
  35.  */
  36. filevisit(f, n, k)
  37. {
  38.     register BUFFER    *bp;
  39.     register WINDOW    *wp;
  40.     register LINE    *lp;
  41.     register int    i;
  42.     register int    s;
  43.     char        bname[NBUFN];
  44.     char        fname[NFILEN];
  45.  
  46.     if ((s=ereply("Visit file: ", fname, NFILEN)) != TRUE)
  47.         return (s);
  48.     adjustcase(fname);
  49.     for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
  50.         if (strcmp(bp->b_fname, fname) == 0) {
  51.             if (--curbp->b_nwnd == 0) {
  52.                 curbp->b_dotp  = curwp->w_dotp;
  53.                 curbp->b_doto  = curwp->w_doto;
  54.                 curbp->b_markp = curwp->w_markp;
  55.                 curbp->b_marko = curwp->w_marko;
  56.             }
  57.             curbp = bp;
  58.             curwp->w_bufp  = bp;
  59.             if (bp->b_nwnd++ == 0) {
  60.                 curwp->w_dotp  = bp->b_dotp;
  61.                 curwp->w_doto  = bp->b_doto;
  62.                 curwp->w_markp = bp->b_markp;
  63.                 curwp->w_marko = bp->b_marko;
  64.             } else {
  65.                 wp = wheadp;
  66.                 while (wp != NULL) {
  67.                     if (wp!=curwp && wp->w_bufp==bp) {
  68.                         curwp->w_dotp  = wp->w_dotp;
  69.                         curwp->w_doto  = wp->w_doto;
  70.                         curwp->w_markp = wp->w_markp;
  71.                         curwp->w_marko = wp->w_marko;
  72.                         break;
  73.                     }
  74.                     wp = wp->w_wndp;
  75.                 }
  76.             }
  77.             lp = curwp->w_dotp;
  78.             i = curwp->w_ntrows/2;
  79.             while (i-- && lback(lp)!=curbp->b_linep)
  80.                 lp = lback(lp);
  81.             curwp->w_linep = lp;
  82.             curwp->w_flag |= WFMODE|WFHARD;
  83.             if (kbdmop == NULL)
  84.                 eprintf("[Old buffer]");
  85.             return (TRUE);
  86.         }
  87.     }
  88.     makename(bname, fname);            /* New buffer name.    */
  89.     while ((bp=bfind(bname, FALSE)) != NULL) {
  90.         s = ereply("Buffer name: ", bname, NBUFN);
  91.         if (s == ABORT)            /* ^G to just quit    */
  92.             return (s);
  93.         if (s == FALSE) {        /* CR to clobber it    */
  94.             makename(bname, fname);
  95.             break;
  96.         }
  97.     }
  98.     if (bp==NULL && (bp=bfind(bname, TRUE))==NULL) {
  99.         eprintf("Cannot create buffer");
  100.         return (FALSE);
  101.     }
  102.     if (--curbp->b_nwnd == 0) {        /* Undisplay.        */
  103.         curbp->b_dotp = curwp->w_dotp;
  104.         curbp->b_doto = curwp->w_doto;
  105.         curbp->b_markp = curwp->w_markp;
  106.         curbp->b_marko = curwp->w_marko;
  107.     }
  108.     curbp = bp;                /* Switch to it.    */
  109.     curwp->w_bufp = bp;
  110.     curbp->b_nwnd++;
  111.     return (readin(fname));            /* Read it in.        */
  112. }
  113.  
  114. /*
  115.  * Read the file "fname" into the current buffer.
  116.  * Make all of the text in the buffer go away, after checking
  117.  * for unsaved changes. This is called by the "read" command, the
  118.  * "visit" command, and the mainline (for "uemacs file"). If the
  119.  * BACKUP conditional is set, then this routine also does the read
  120.  * end of backup processing. The BFBAK flag, if set in a buffer,
  121.  * says that a backup should be taken. It is set when a file is
  122.  * read in, but not on a new file (you don't need to make a backup
  123.  * copy of nothing). Return a standard status. Print a summary
  124.  * (lines read, error message) out as well.
  125.  */
  126. readin(fname)
  127. char    fname[];
  128. {
  129.     register LINE    *lp1;
  130.     register LINE    *lp2;
  131.     register int    i;
  132.     register WINDOW    *wp;
  133.     register BUFFER    *bp;
  134.     register int    s;
  135.     register int    nbytes;
  136.     register int    nline;
  137.     char        line[NLINE];
  138.  
  139.     bp = curbp;                /* Cheap.        */
  140.     if ((s=bclear(bp)) != TRUE)        /* Might be old.    */
  141.         return (s);
  142. #if    BACKUP
  143.     bp->b_flag &= ~(BFCHG|BFBAK);        /* No change, backup.    */
  144. #else
  145.     bp->b_flag &= ~BFCHG;            /* No change.        */
  146. #endif
  147.     strcpy(bp->b_fname, fname);
  148.     if ((s=ffropen(fname)) == FIOERR)     /* Hard file open.    */
  149.         goto out;
  150.     if (s == FIOFNF) {            /* File not found.    */
  151.         if (kbdmop == NULL)
  152.             eprintf("[New file]");
  153.         goto out;
  154.     }
  155.     nline = 0;
  156.     while ((s=ffgetline(line, NLINE)) == FIOSUC) {
  157.         nbytes = strlen(line);
  158.         if ((lp1=lalloc(nbytes)) == NULL) {
  159.             s = FIOERR;        /* Keep message on the    */
  160.             break;            /* display.        */
  161.         }
  162.         lp2 = lback(curbp->b_linep);
  163.         lp2->l_fp = lp1;
  164.         lp1->l_fp = curbp->b_linep;
  165.         lp1->l_bp = lp2;
  166.         curbp->b_linep->l_bp = lp1;
  167.         for (i=0; i<nbytes; ++i)
  168.             lputc(lp1, i, line[i]);
  169.         ++nline;
  170.     }
  171.     ffclose();                /* Ignore errors.    */
  172.     if (s==FIOEOF && kbdmop==NULL) {    /* Don't zap an error.    */
  173.         if (nline == 1)
  174.             eprintf("[Read 1 line]");
  175.         else
  176.             eprintf("[Read %d lines]", nline);
  177.     }
  178. #if    BACKUP
  179.     curbp->b_flag |= BFBAK;            /* Need a backup.    */
  180. #endif
  181. out:
  182.     for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  183.         if (wp->w_bufp == curbp) {
  184.             wp->w_linep = lforw(curbp->b_linep);
  185.             wp->w_dotp  = lforw(curbp->b_linep);
  186.             wp->w_doto  = 0;
  187.             wp->w_markp = NULL;
  188.             wp->w_marko = 0;
  189.             wp->w_flag |= WFMODE|WFHARD;
  190.         }
  191.     }
  192.     if (s == FIOERR)            /* False if error.    */
  193.         return (FALSE);
  194.     return (TRUE);
  195. }
  196.  
  197. /*
  198.  * Take a file name, and from it
  199.  * fabricate a buffer name. This routine knows
  200.  * about the syntax of file names on the target system.
  201.  * BDC1        left scan delimiter.
  202.  * BDC2        optional second left scan delimiter.
  203.  * BDC3        optional right scan delimiter.
  204.  */
  205. makename(bname, fname)
  206. char    bname[];
  207. char    fname[];
  208. {
  209.     register char    *cp1;
  210.     register char    *cp2;
  211.  
  212.     cp1 = &fname[0];
  213.     while (*cp1 != 0)
  214.         ++cp1;
  215. #ifdef    BDC2
  216.     while (cp1!=&fname[0] && cp1[-1]!=BDC1 && cp1[-1]!=BDC2)
  217.         --cp1;
  218. #else
  219.     while (cp1!=&fname[0] && cp1[-1]!=BDC1)
  220.         --cp1;
  221. #endif
  222.     cp2 = &bname[0];
  223. #ifdef    BDC3
  224.     while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=BDC3)
  225.         *cp2++ = *cp1++;
  226. #else
  227.     while (cp2!=&bname[NBUFN-1] && *cp1!=0)
  228.         *cp2++ = *cp1++;
  229. #endif
  230.     *cp2 = 0;
  231. }
  232.  
  233. /*
  234.  * Ask for a file name, and write the
  235.  * contents of the current buffer to that file.
  236.  * Update the remembered file name and clear the
  237.  * buffer changed flag. This handling of file names
  238.  * is different from the earlier versions, and
  239.  * is more compatable with Gosling EMACS than
  240.  * with ITS EMACS.
  241.  */
  242. filewrite(f, n, k)
  243. {
  244.     register WINDOW    *wp;
  245.     register int    s;
  246.     char        fname[NFILEN];
  247.  
  248.     if ((s=ereply("Write file: ", fname, NFILEN)) != TRUE)
  249.         return (s);
  250.     adjustcase(fname);
  251.     if ((s=writeout(fname)) == TRUE) {
  252.         strcpy(curbp->b_fname, fname);
  253.         curbp->b_flag &= ~BFCHG;
  254.         wp = wheadp;            /* Update mode lines.    */
  255.         while (wp != NULL) {
  256.             if (wp->w_bufp == curbp)
  257.                 wp->w_flag |= WFMODE;
  258.             wp = wp->w_wndp;
  259.         }
  260.     }
  261. #if    BACKUP
  262.     curbp->b_flag &= ~BFBAK;        /* No backup.        */
  263. #endif
  264.     return (s);
  265. }
  266.  
  267. /*
  268.  * Save the contents of the current buffer back into
  269.  * its associated file. Do nothing if there have been no changes
  270.  * (is this a bug, or a feature). Error if there is no remembered
  271.  * file name. If this is the first write since the read or visit,
  272.  * then a backup copy of the file is made.
  273.  */
  274. filesave(f, n, k)
  275. {
  276.     register WINDOW    *wp;
  277.     register int    s;
  278.  
  279.     if ((curbp->b_flag&BFCHG) == 0)        /* Return, no changes.    */
  280.         return (TRUE);
  281.     if (curbp->b_fname[0] == 0) {        /* Must have a name.    */
  282.         eprintf("No file name");
  283.         return (FALSE);
  284.     }
  285. #if    BACKUP
  286.     if ((curbp->b_flag&BFBAK) != 0) {
  287.         s = fbackupfile(curbp->b_fname);
  288.         if (s == ABORT)            /* Hard error.        */
  289.             return (s);
  290.         if (s == FALSE            /* Softer error.    */
  291.         && (s=eyesno("Backup error, save anyway")) != TRUE)
  292.             return (s);
  293.     }
  294. #endif
  295.     if ((s=writeout(curbp->b_fname)) == TRUE) {
  296.         curbp->b_flag &= ~BFCHG;
  297.         wp = wheadp;            /* Update mode lines.    */
  298.         while (wp != NULL) {
  299.             if (wp->w_bufp == curbp)
  300.                 wp->w_flag |= WFMODE;
  301.             wp = wp->w_wndp;
  302.         }
  303.     }
  304. #if    BACKUP
  305.     curbp->b_flag &= ~BFBAK;        /* No backup.        */
  306. #endif
  307.     return (s);
  308. }
  309.  
  310. /*
  311.  * This function performs the details of file
  312.  * writing. Uses the file management routines in the
  313.  * "fileio.c" package. The number of lines written is
  314.  * displayed. Sadly, it looks inside a LINE; provide
  315.  * a macro for this. Most of the grief is error
  316.  * checking of some sort.
  317.  */
  318. writeout(fn)
  319. char    *fn;
  320. {
  321.     register int    s;
  322.     register LINE    *lp;
  323.     register int    nline;
  324.  
  325.     if ((s=ffwopen(fn)) != FIOSUC)        /* Open writes message.    */
  326.         return (FALSE);
  327.     lp = lforw(curbp->b_linep);        /* First line.        */
  328.     nline = 0;                /* Number of lines.    */
  329.     while (lp != curbp->b_linep) {
  330.         if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
  331.             break;
  332.         ++nline;
  333.         lp = lforw(lp);
  334.     }
  335.     if (s == FIOSUC) {            /* No write error.    */
  336.         s = ffclose();
  337.         if (s==FIOSUC && kbdmop==NULL) {
  338.             if (nline == 1)
  339.                 eprintf("[Wrote 1 line]");
  340.             else
  341.                 eprintf("[Wrote %d lines]", nline);
  342.         }
  343.     } else                    /* Ignore close error    */
  344.         ffclose();            /* if a write error.    */
  345.     if (s != FIOSUC)            /* Some sort of error.    */
  346.         return (FALSE);
  347.     return (TRUE);
  348. }
  349.  
  350. /*
  351.  * The command allows the user
  352.  * to modify the file name associated with
  353.  * the current buffer. It is like the "f" command
  354.  * in UNIX "ed". The operation is simple; just zap
  355.  * the name in the BUFFER structure, and mark the windows
  356.  * as needing an update. You can type a blank line at the
  357.  * prompt if you wish.
  358.  */
  359. filename(f, n, k)
  360. {
  361.     register WINDOW    *wp;
  362.     register int    s;
  363.     char         fname[NFILEN];
  364.  
  365.     if ((s=ereply("Name: ", fname, NFILEN)) == ABORT)
  366.         return (s);
  367.     adjustcase(fname);
  368.     strcpy(curbp->b_fname, fname);        /* Fix name.        */
  369.     wp = wheadp;                /* Update mode lines.    */
  370.     while (wp != NULL) {
  371.         if (wp->w_bufp == curbp)
  372.             wp->w_flag |= WFMODE;
  373.         wp = wp->w_wndp;
  374.     }
  375. #if    BACKUP
  376.     curbp->b_flag &= ~BFBAK;        /* No backup.        */
  377. #endif
  378.     return (TRUE);
  379. }
  380.